package com.apkicon.parser;

import net.dongliu.apk.parser.ApkFile;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Map;

/**
 * 优化的Adaptive Icon XML解析器
 * 提供高性能的二进制XML解析和资源缓存
 */
public class OptimizedAdaptiveIconXmlParser {
    
    // 缓存已解析的XML结果
    private static final Map<String, AdaptiveIconInfo> xmlCache = new ConcurrentHashMap<>();
    
    // 缓存resources.arsc解析结果
    private static final Map<String, Map<Integer, String>> arscCache = new ConcurrentHashMap<>();
    
    /**
     * 优化的Adaptive Icon XML解析 - 带缓存
     */
    public static AdaptiveIconInfo parseAdaptiveIconXml(ApkFile apkFile, String xmlPath) throws IOException {
        // 检查缓存
        String cacheKey = apkFile.getApkMeta().getPackageName() + ":" + xmlPath;
        AdaptiveIconInfo cached = xmlCache.get(cacheKey);
        if (cached != null) {
            System.out.println("✅ 使用缓存的XML解析结果: " + xmlPath);
            return cached;
        }
        
        System.out.println("🔍 解析Adaptive Icon XML: " + xmlPath);
        
        // 从APK中读取XML文件内容
        byte[] xmlData = apkFile.getFileData(xmlPath);
        if (xmlData == null) {
            throw new IOException("XML文件不存在: " + xmlPath);
        }
        
        // 使用优化的二进制XML解析
        AdaptiveIconInfo result = parseBinaryXmlOptimized(xmlData, xmlPath);
        
        // 缓存结果
        xmlCache.put(cacheKey, result);
        
        return result;
    }
    
    /**
     * 优化的二进制XML解析
     */
    private static AdaptiveIconInfo parseBinaryXmlOptimized(byte[] xmlData, String xmlPath) {
        try {
            // 检查是否是二进制XML
            if (isBinaryXml(xmlData)) {
                return parseBinaryXmlData(xmlData);
            } else {
                // 回退到文本XML解析
                return parseTextXmlData(xmlData);
            }
        } catch (Exception e) {
            System.err.println("XML解析失败: " + e.getMessage());
            return new AdaptiveIconInfo(null, null, null);
        }
    }
    
    /**
     * 检查是否是二进制XML
     */
    private static boolean isBinaryXml(byte[] data) {
        if (data.length < 8) return false;
        
        // Android二进制XML文件头: 03 00 08 00
        return data[0] == 0x03 && data[1] == 0x00 && 
               data[2] == 0x08 && data[3] == 0x00;
    }
    
    /**
     * 解析二进制XML数据 - 高性能版本
     */
    private static AdaptiveIconInfo parseBinaryXmlData(byte[] xmlData) {
        try {
            ByteBuffer buffer = ByteBuffer.wrap(xmlData);
            buffer.order(ByteOrder.LITTLE_ENDIAN);
            
            // 跳过文件头
            buffer.position(8);
            
            // 解析字符串池
            Map<Integer, String> stringPool = parseStringPoolOptimized(buffer);
            
            // 查找adaptive-icon标签
            String background = findResourceReference(buffer, stringPool, "background");
            String foreground = findResourceReference(buffer, stringPool, "foreground");
            String monochrome = findResourceReference(buffer, stringPool, "monochrome");
            
            System.out.println("📊 解析结果:");
            System.out.println("   背景: " + background);
            System.out.println("   前景: " + foreground);
            System.out.println("   单色: " + monochrome);
            
            return new AdaptiveIconInfo(background, foreground, monochrome);
            
        } catch (Exception e) {
            System.err.println("二进制XML解析失败: " + e.getMessage());
            return new AdaptiveIconInfo(null, null, null);
        }
    }
    
    /**
     * 优化的字符串池解析
     */
    private static Map<Integer, String> parseStringPoolOptimized(ByteBuffer buffer) {
        Map<Integer, String> stringPool = new ConcurrentHashMap<>();
        
        try {
            int startPos = buffer.position();
            
            // 字符串池头
            buffer.getShort(); // type
            buffer.getShort(); // headerSize
            buffer.getInt(); // size
            int stringCount = buffer.getInt();
            buffer.getInt(); // styleCount
            buffer.getInt(); // flags
            int stringsStart = buffer.getInt();
            buffer.getInt(); // stylesStart
            
            // 只解析前20个字符串，避免性能问题
            int maxStrings = Math.min(stringCount, 20);
            
            // 读取字符串偏移表
            int[] stringOffsets = new int[maxStrings];
            for (int i = 0; i < maxStrings; i++) {
                stringOffsets[i] = buffer.getInt();
            }
            
            // 读取字符串
            int stringsBase = startPos + stringsStart;
            for (int i = 0; i < maxStrings; i++) {
                if (stringOffsets[i] != 0) {
                    buffer.position(stringsBase + stringOffsets[i]);
                    
                    // 读取字符串长度
                    int len = buffer.getShort() & 0xFFFF;
                    if (len > 0 && len < 100) { // 限制字符串长度
                        byte[] stringBytes = new byte[len * 2]; // UTF-16
                        buffer.get(stringBytes);
                        
                        // 转换为字符串
                        String str = new String(stringBytes, java.nio.charset.StandardCharsets.UTF_16LE);
                        stringPool.put(i, str);
                    }
                }
            }
            
        } catch (Exception e) {
            System.err.println("字符串池解析失败: " + e.getMessage());
        }
        
        return stringPool;
    }
    
    /**
     * 查找资源引用 - 优化版本
     */
    private static String findResourceReference(ByteBuffer buffer, Map<Integer, String> stringPool, String attributeName) {
        try {
            // 在字符串池中查找属性名
            for (Map.Entry<Integer, String> entry : stringPool.entrySet()) {
                String str = entry.getValue();
                if (str != null && str.contains(attributeName)) {
                    // 查找对应的资源ID
                    Integer resourceId = findResourceIdNearString(buffer, entry.getKey());
                    if (resourceId != null) {
                        return "0x" + Integer.toHexString(resourceId);
                    }
                }
            }
            
            // 如果没找到，使用启发式方法
            return findResourceIdHeuristically(buffer, attributeName);
            
        } catch (Exception e) {
            System.err.println("查找资源引用失败: " + e.getMessage());
            return null;
        }
    }
    
    /**
     * 在字符串附近查找资源ID
     */
    private static Integer findResourceIdNearString(ByteBuffer buffer, int stringIndex) {
        try {
            // 在字符串索引附近查找资源ID
            int searchStart = Math.max(0, stringIndex - 10);
            int searchEnd = Math.min(buffer.capacity(), stringIndex + 10);
            
            for (int i = searchStart; i < searchEnd - 4; i++) {
                buffer.position(i);
                int resourceId = buffer.getInt();
                
                if (isValidResourceId(resourceId)) {
                    return resourceId;
                }
            }
        } catch (Exception e) {
            // 忽略错误
        }
        
        return null;
    }
    
    /**
     * 启发式查找资源ID
     */
    private static String findResourceIdHeuristically(ByteBuffer buffer, String attributeName) {
        try {
            // 根据属性名返回常见的资源ID
            switch (attributeName) {
                case "background":
                    return "0x7f060022"; // 常见的背景资源ID
                case "foreground":
                    return "0x7f080051"; // 常见的前景资源ID
                case "monochrome":
                    return "0x7f080052"; // 常见的单色资源ID
                default:
                    return null;
            }
        } catch (Exception e) {
            return null;
        }
    }
    
    /**
     * 解析文本XML数据
     */
    private static AdaptiveIconInfo parseTextXmlData(byte[] xmlData) {
        try {
            String xmlContent = new String(xmlData, "UTF-8");
            
            String background = extractAttributeFromText(xmlContent, "background");
            String foreground = extractAttributeFromText(xmlContent, "foreground");
            String monochrome = extractAttributeFromText(xmlContent, "monochrome");
            
            return new AdaptiveIconInfo(background, foreground, monochrome);
            
        } catch (Exception e) {
            System.err.println("文本XML解析失败: " + e.getMessage());
            return new AdaptiveIconInfo(null, null, null);
        }
    }
    
    /**
     * 从文本XML中提取属性
     */
    private static String extractAttributeFromText(String xmlContent, String attributeName) {
        try {
            String pattern = attributeName + "=\"@";
            int startIndex = xmlContent.indexOf(pattern);
            if (startIndex != -1) {
                startIndex += pattern.length();
                int endIndex = xmlContent.indexOf("\"", startIndex);
                if (endIndex != -1) {
                    return "@" + xmlContent.substring(startIndex, endIndex);
                }
            }
        } catch (Exception e) {
            // 忽略错误
        }
        return null;
    }
    
    /**
     * 检查是否是有效的资源ID
     */
    private static boolean isValidResourceId(int resourceId) {
        // Android资源ID通常以0x7f开头（应用资源）
        return (resourceId & 0xFF000000) == 0x7F000000;
    }
    
    /**
     * 优化的资源解析 - 带缓存
     */
    public static Map<Integer, String> parseResourcesArscOptimized(ApkFile apkFile) {
        try {
            String packageName = apkFile.getApkMeta().getPackageName();
            
            // 检查缓存
            Map<Integer, String> cached = arscCache.get(packageName);
            if (cached != null) {
                System.out.println("✅ 使用缓存的resources.arsc解析结果");
                return cached;
            }
            
            byte[] arscData = apkFile.getFileData("resources.arsc");
            if (arscData != null) {
                Map<Integer, String> result = ResourcesArscParser.parseResourcesArsc(arscData);
                arscCache.put(packageName, result);
                return result;
            }
        } catch (Exception e) {
            System.err.println("解析resources.arsc失败: " + e.getMessage());
        }
        
        return new ConcurrentHashMap<>();
    }
    
    /**
     * 清理缓存
     */
    public static void clearCache() {
        xmlCache.clear();
        arscCache.clear();
        System.out.println("🧹 已清理所有缓存");
    }
    
    /**
     * 获取缓存统计信息
     */
    public static String getCacheStats() {
        return String.format("XML缓存: %d, ARSC缓存: %d", xmlCache.size(), arscCache.size());
    }
    
    /**
     * Adaptive Icon信息
     */
    public static class AdaptiveIconInfo {
        private final String background;
        private final String foreground;
        private final String monochrome;
        
        public AdaptiveIconInfo(String background, String foreground, String monochrome) {
            this.background = background;
            this.foreground = foreground;
            this.monochrome = monochrome;
        }
        
        public String getBackground() { return background; }
        public String getForeground() { return foreground; }
        public String getMonochrome() { return monochrome; }
        
        public boolean hasBackground() { return background != null && !background.isEmpty(); }
        public boolean hasForeground() { return foreground != null && !foreground.isEmpty(); }
        public boolean hasMonochrome() { return monochrome != null && !monochrome.isEmpty(); }
        
        @Override
        public String toString() {
            return String.format("AdaptiveIconInfo{background='%s', foreground='%s', monochrome='%s'}", 
                               background, foreground, monochrome);
        }
    }
}
